#include "includes.h"
#include "./wrap.h"
#define PORT atoi(argv[1])
#define MAX_SZIE (1024)
void fn(char *p);
int main(int argc ,char** argv)
{
    int serversocket = 0;
    int maxi = -1;
    int ret = 0;
    int epfd = 0;
    struct sockaddr_in addr, client_addr;
    if(argc !=2){
        printf("usage %s port(num).\n",argv[0]);
        exit(-1);
    }
    socklen_t socklen = sizeof(addr);
    struct epoll_event eEvent[MAX_SZIE], tep;
    memset(&addr, 0, sizeof(addr));
    serversocket = Socket(AF_INET, SOCK_STREAM, 0);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    Bind(serversocket, (struct sockaddr *)&addr, sizeof(addr));
    Listen(serversocket, 10);
    epfd = epoll_create(1024);
    if (epfd == -1)
    {
        sys_error("epoll error");
    }
    tep.events = EPOLLIN;
    tep.data.fd = serversocket;
    epoll_ctl(epfd, EPOLL_CTL_ADD, serversocket, &tep);
    maxi = 0;
    for (;;)
    {
        ret = epoll_wait(epfd, eEvent, MAX_SZIE, -1);
        if (ret == -1)
        {
            sys_error("epoll error");
        }
        else if (ret > 0)
        {
            for (size_t i = 0; i < ret; i++)
            {
                if (eEvent[i].data.fd == serversocket)
                {

                    int fd = Accept(serversocket, (struct sockaddr *)&client_addr, &socklen);
                    char buf[100];
                    CLEAR_ARRAY(buf);
                    printf("New connection from IP:%s,port:%d\n", inet_ntop(AF_INET, &(client_addr.sin_addr), buf, sizeof(buf)),
                           ntohs(client_addr.sin_port));
                    size_t i;
                    tep.data.fd = fd;
                    epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &tep);
                }
                else
                {
                    char buf[BUFSIZ];
                    CLEAR_ARRAY(buf);
                    size_t len = Read(eEvent[i].data.fd, buf, sizeof(buf));
                    if (len == -1)
                    {
                        if (errno == ECONNRESET)
                        {
                            goto close;
                        }
                    }
                    if (len == 0)
                    {
                    close:
                        Close(eEvent[i].data.fd);
                        epoll_ctl(epfd, EPOLL_CTL_DEL, eEvent[i].data.fd, &tep);
                        printf("client disconnected\n");
                        continue;
                    }
                    fn(buf);
                    Write(eEvent[i].data.fd, buf, len);
                }
            }
        }
    }
}
void fn(char *p)
{
    if (!p)
    {
        return;
    }
    while (*p)
    {
        *p = toupper(*p);
        p++;
    }
}